// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// #include <unsupported/Eigen/CXX11/Tensor>
// #undef min



#include "utils/transforms.h"
#include "utils/model_config.h"
#include "seg_predictor.h"

namespace paddle_infer {
using std::chrono::duration_cast;

SegPredictor::SegPredictor(LogInfo *log_ifo):
  log_ifo(log_ifo) {
}

int SegPredictor::Run(cv::Mat& img, 
            std::vector<BaseInfoPD*> &det_infos, 
            PDModelManager *mng,
            int md_idx)
{
    if (mng->configs[md_idx]->algorithm == pd_seg){
        return RunSeg(img, det_infos, mng, md_idx);
    }else{
        return pd_not_implement_error;
    }
}


// paddle 2.1
int SegPredictor::RunSeg(cv::Mat& img, 
        std::vector<BaseInfoPD*> &seg_infos, 
        PDModelManager *mng,
        int md_idx)
{
  int ret = 0;
  if (log_ifo->log_level_4) spdlog::get("logger")->info("1.2.3.0 RunSeg");

  if (img.empty()){return PD_IMAGE_EMPTY_ERROR;}
  PDModelConfig *cfg = mng->configs[md_idx];
  ImageBlob img_blob = ImageBlob();
  cfg->transforms->run(img, img_blob, cfg);
  if (log_ifo->log_level_4) spdlog::get("logger")->info("1.2.3.1 RunSeg");

  auto input_names = mng->predictors[md_idx]->GetInputNames();
  if (log_ifo->log_level_4) { log_tensor_shape("input_names", input_names); }

  auto im_tensor = mng->predictors[md_idx]->GetInputTensor("x");
  if (cfg->data_format == "CHW"){ im_tensor->Reshape({ 1, cfg->channels, img_blob.new_im_shape[0], img_blob.new_im_shape[1] });}
  else { im_tensor->Reshape({ 1, img_blob.new_im_shape[0], img_blob.new_im_shape[1], cfg->channels }); }
  im_tensor->CopyFromCpu(img_blob.im_data.data());

  auto t1 = std::chrono::high_resolution_clock::now();
  mng->predictors[md_idx]->ZeroCopyRun();
  if (log_ifo->log_level_4) {
    auto t2 = std::chrono::high_resolution_clock::now();
    auto duration = duration_cast<std::chrono::microseconds>
                    (t2 - t1).count();
    spdlog::get("logger")->info("runtime = {}ms", duration * 1.0 / 1000);
  }
  if (log_ifo->log_level_4) spdlog::get("logger")->info("1.2.3.2 RunSeg");

  std::vector<int64_t> label_map;
  std::vector<float> score_map;
  auto output_names = mng->predictors[md_idx]->GetOutputNames();
  if (log_ifo->log_level_4) { log_tensor_shape("output_names", output_names); }

  // get labelmap
  auto output_tensor = mng->predictors[md_idx]->GetOutputTensor(output_names[0]);
  std::vector<int> output_shape = output_tensor->shape();
  int size = std::accumulate(output_shape.begin(), output_shape.end(), 1, std::multiplies<int>());
  if (log_ifo->log_level_4) { log_tensor_shape("output_tensor", output_shape); }
  label_map.resize(size);
  output_tensor->copy_to_cpu(label_map.data());
  if (log_ifo->log_level_4) spdlog::get("logger")->info("1.2.3.3 RunSeg");

  std::vector<uint8_t> label_uint8(label_map.begin(), label_map.end());
  cv::Mat mask = cv::Mat(output_shape[1], output_shape[2], CV_8UC1, label_uint8.data());
  cv::resize(mask, mask, cv::Size(img_blob.ori_im_shape[1], img_blob.ori_im_shape[0]), 0, 0, cv::INTER_NEAREST);
  if (log_ifo->log_level_4) spdlog::get("logger")->info("1.2.3.4 RunSeg");

  ret = output_poly(mask, seg_infos, cfg);
  if (log_ifo->log_level_4) spdlog::get("logger")->info("1.2.3.5 RunSeg");
  return ret;

  // // get scoremap
  // auto output_score_tensor = mng->predictors[md_idx]->GetOutputTensor(output_names[1]);
  // std::vector<int> output_score_shape = output_score_tensor->shape();
  // size = 1;
  // spdlog::get("logger")->info("output_score_shape size of outputs[" << 1 << "]: (");
  // for (const auto& i : output_score_shape) { size *= i; spdlog::get("logger")->info(i << ","); }
  // spdlog::get("logger")->info(")");

  // score_map.resize(size);
  // output_score_tensor->copy_to_cpu(score_map.data());


  // // get origin image result
  // std::vector<uint8_t> label_uint8(label_map.begin(), label_map.end());
  // cv::Mat mask_label(output_label_shape[1],
  //                    output_label_shape[2],
  //                    CV_8UC1,
  //                    label_uint8.data());
  // // cv::Mat mask_score(output_score_shape[2],
  // //                    output_score_shape[3],
  // //                    CV_32FC1,
  // //                    score_map.data());
  // int idx = 1;
  // int len_postprocess = img_blob.im_shape_record.size();
  // for (std::vector<std::string>::reverse_iterator iter =
  //          img_blob.deal_order.rbegin();
  //      iter != img_blob.deal_order.rend();
  //      ++iter) {
  //   if (*iter == "padding") {
  //     auto before_shape = img_blob.im_shape_record[len_postprocess - idx];
  //     img_blob.im_shape_record.pop_back();
  //     auto padding_h = before_shape[0];
  //     auto padding_w = before_shape[1];
  //     mask_label = mask_label(cv::Rect(0, 0, padding_w, padding_h));
  //     // mask_score = mask_score(cv::Rect(0, 0, padding_w, padding_h));
  //   } else if (*iter == "resize") {
  //     auto before_shape = img_blob.im_shape_record[len_postprocess - idx];
  //     img_blob.im_shape_record.pop_back();
  //     auto resize_h = before_shape[0];
  //     auto resize_w = before_shape[1];
  //     cv::resize(mask_label,
  //                mask_label,
  //                cv::Size(resize_w, resize_h),
  //                0,
  //                0,
  //                cv::INTER_NEAREST);
  //     // cv::resize(mask_score,
  //     //            mask_score,
  //     //            cv::Size(resize_w, resize_h),
  //     //            0,
  //     //            0,
  //     //            cv::INTER_LINEAR);
  //   }
  //   ++idx;
  // }


}

int SegPredictor::output_poly(cv::Mat& label_mask, 
                std::vector<BaseInfoPD*>& seg_infos, 
                PDModelConfig* cfg) {
  int ret = 0;
  int max_label_size = 256;

  // continue background which clas_idx=0
  for (int clas_idx = 1; clas_idx< cfg->label_list.size(); clas_idx++) {
    std::vector<uchar> vec_map(max_label_size, 0);
    vec_map[clas_idx] = 255;
    cv::Mat mat_map = cv::Mat(max_label_size, 1, CV_8UC1, vec_map.data());
    cv::Mat mask;
    cv::LUT(label_mask, mat_map, mask);
    seg_infos.push_back(new DetInfoPD(0.99, clas_idx, cv::Rect(), cfg->label_list[clas_idx], mask));
    if (log_ifo->log_level_3) {
      cv::imwrite(log_ifo->get_log_path()+"/"+ \
                      std::to_string(log_ifo->counter()) \
                      + "_" + std::to_string(clas_idx)+"_color_mask.jpg", mask);
    }
  }

  if (log_ifo->log_level_3) {
    auto colormap = GenerateColorMap(cfg->label_list.size());
    cv::Mat color_mask = cv::Mat::zeros(label_mask.size(), CV_8UC3);
    for (int i = 0; i < label_mask.rows; i++) {
      for (int j = 0; j < label_mask.cols; j++) {
        int category_id = static_cast<int>(label_mask.at<uchar>(i, j));
        color_mask.at<cv::Vec3b>(i, j)[0] = colormap[3 * category_id + 0];
        color_mask.at<cv::Vec3b>(i, j)[1] = colormap[3 * category_id + 1];
        color_mask.at<cv::Vec3b>(i, j)[2] = colormap[3 * category_id + 2];
      }
    }
    cv::imwrite(log_ifo->get_log_path()+"/"+ \
                    std::to_string(log_ifo->counter()) \
                    +"_color_mask.jpg", color_mask);
  }
  return ret;
}
// paddle 2.0
// int SegPredictor::RunSeg(cv::Mat& img, 
//         std::vector<DetInfoPD> &det_infos, 
//         PDModelManager *mng,
//         int md_idx)
// {
//   int ret = 0;
//   PDModelConfig *cfg = mng->configs[md_idx];

//   int real_buffer_size = cfg->channels \
//           * cfg->image_shape[0] * cfg->image_shape[1];
//   std::vector<float> input_buffer(real_buffer_size, 0.);

//   ImageBlob* img_blob = new ImageBlob(img);
//   img_blob.im_data = input_buffer.data() ;

//   if (mng->configs[md_idx]->pre_processor == "SegPreProcessor"){
//       ret = seg_pp_->single_process(img, img_blob, cfg);
//   }
//   else{
//       return not_implement_error;
//   }
//   auto input_names = mng->predictors[md_idx]->GetInputNames();
//   for (const auto& tensor_name : input_names) { 
//     if (log_info_->log_level_3) { spdlog::get("logger")->info("tensor_name: " << tensor_name);}
//   }
//   auto im_tensor = mng->predictors[md_idx]->GetInputHandle("x");
//   if (cfg->is_channel_first){
//   im_tensor->Reshape({ 1, cfg->channels,
//                   cfg->image_shape[0] , cfg->image_shape[1] });
//   }
//   else
//   {
//   im_tensor->Reshape({ 1, cfg->image_shape[0] , 
//                       cfg->image_shape[1], cfg->channels });
//   }
//   im_tensor->CopyFromCpu(input_buffer.data());

//   auto t1 = std::chrono::high_resolution_clock::now();
//   mng->predictors[md_idx]->Run();
//   auto t2 = std::chrono::high_resolution_clock::now();
//   auto duration = duration_cast<std::chrono::microseconds>
//                   (t2 - t1).count();
//   spdlog::get("logger")->info("runtime = " << duration);

//   auto output_names = mng->predictors[md_idx]->GetOutputNames();
//   auto output_t = mng->predictors[md_idx]->GetOutputHandle(
//                                       output_names[0]);
//   std::vector<int> output_shape = output_t->shape();

//   int out_num = 1;
//   spdlog::get("logger")->info("size of outputs[" << 0 << "]: (");
//   for (int j = 0; j < output_shape.size(); ++j) {
//       out_num *= output_shape[j];
//       spdlog::get("logger")->info(output_shape[j] << ",");
//   }
//   spdlog::get("logger")->info(")");

//   std::vector<int64> out_data(out_num, 0.);
//   output_t->CopyToCpu(out_data.data());

//   // output_mask(img, out_data.data(), 
//   //     out_num, img_blob, cfg, det_infos);
//    return 0;

// }


int SegPredictor::RunSeg(std::vector<cv::Mat>& imgs, 
            std::vector<DetInfoPD> &det_infos, 
            PDModelManager *mng,
            int md_idx)
{
  // int ret = 0;
  // PDModelConfig *cfg = mng->configs[md_idx];
  // spdlog::get("logger")->info("runtime =  6");

  // auto total_size = imgs.size();
  // int default_batch_size = std::min(cfg->batch_size,
  //                                     static_cast<int>(total_size));
  // int batch = total_size / default_batch_size
  //             + ((total_size % default_batch_size) != 0);
  // spdlog::get("logger")->info("runtime =  7");

  // for (int u = 0; u < batch; ++u) {
  //     int batch_size = default_batch_size;
  //     if (u == (batch - 1) && (total_size % default_batch_size)) {
  //         batch_size = total_size % default_batch_size;
  //     }

  //     int real_buffer_size = batch_size * cfg->channels \
  //             * cfg->image_shape[0] * cfg->image_shape[1];
  //     std::vector<float> input_buffer(real_buffer_size, 0.);

  //     std::vector<ImageBlob*> data_inputs;
  //     std::vector<cv::Mat&> imgs_batch;
  //     for (int i = 0; i < batch_size; ++i) {
  //         int idx = u * default_batch_size + i;
  //         imgs_batch.push_back(imgs[idx]);
  //         ImageBlob* ib = new ImageBlob(imgs[idx]);
  //         ib->im_data = input_buffer.data() + i * cfg->channels \
  //                     * cfg->image_shape[0] * cfg->image_shape[1];
  //         data_inputs.push_back(ib);
  //     }
  // spdlog::get("logger")->info("runtime =  8");

  //     if (mng->configs[md_idx]->pre_processor == "SegPreProcessor"){
  //         ret = seg_pp_->batch_process(imgs_batch, data_inputs, cfg);
  //     }
  //     else{
  //         return not_implement_error;
  //     }
  // spdlog::get("logger")->info("runtime =  15");

  //     auto im_tensor = mng->predictors[md_idx]->GetInputHandle("image");
  //     if (cfg->is_channel_first){
  //     im_tensor->Reshape({ batch_size, cfg->channels,
  //                     cfg->image_shape[0] , cfg->image_shape[1] });
  //     }else{
  //     im_tensor->Reshape({ batch_size, cfg->image_shape[0] , 
  //                         cfg->image_shape[1], cfg->channels });
  //     }
  //     im_tensor->CopyFromCpu(input_buffer.data());
  // spdlog::get("logger")->info("runtime =  16");

  //     auto t1 = std::chrono::high_resolution_clock::now();
  //     mng->predictors[md_idx]->Run();
  //     auto t2 = std::chrono::high_resolution_clock::now();
  //     auto duration = duration_cast<std::chrono::microseconds>
  //                     (t2 - t1).count();
  //     spdlog::get("logger")->info("runtime = " << duration);

  //     auto output_names = mng->predictors[md_idx]->GetOutputNames();
  //     auto output_t = mng->predictors[md_idx]->GetOutputHandle(
  //                                         output_names[0]);
  //     std::vector<int> output_shape = output_t->shape();

  //     int out_num = 1;
  //     spdlog::get("logger")->info("size of outputs[" << 0 << "]: (");
  //     for (int j = 0; j < output_shape.size(); ++j) {
  //         out_num *= output_shape[j];
  //         spdlog::get("logger")->info(output_shape[j] << ",");
  //     }
  //     spdlog::get("logger")->info(")");

  //     std::vector<float> out_data(out_num, 0.);
  //     output_t->CopyToCpu(out_data.data());
  //     for (int i = 0; i < batch_size; ++i) {
  //         float* out_addr = out_data.data()
  //                         + (out_num / batch_size) * i;
  //         output_mask(imgs_batch[i], out_addr, 
  //             out_num / batch_size, data_inputs[i], cfg, det_infos);
  //     }
  // }
  return 0;

        // if (_model_config._use_pr) {
        //         std::vector<int64_t> out_data;
        //         out_data.resize(out_num);
        //         output_t->copy_to_cpu(out_data.data());
        //         std::vector<uchar> mask_data;
        //         mask_data.resize(out_num);
        //         auto addr = reinterpret_cast<int64_t*>(out_data.data());
        //         for (int r = 0; r < out_num; ++r) {
        //             mask_data[r] = (int)(addr[r]);
        //         }
        //         for (int r = 0; r < batch_size; ++r) {
        //             cv::Mat mask_png = cv::Mat(eval_height, eval_width, CV_8UC1);
        //             mask_png.data = mask_data.data() + eval_height*eval_width*r;
        //             auto name = imgs_batch[r];
        //             auto pos = name.rfind(".");
        //             name[pos] = '_';
        //             std::string mask_save_name = name + "_mask.png";
        //             cv::imwrite(mask_save_name, mask_png);
        //         }
        //         continue;
        // }
}


int SegPredictor::output_mask(cv::Mat& img, 
    float* p_out, int length,
    ImageBlob* datas, PDModelConfig *cfg,
    std::vector<DetInfoPD> &det_infos)
{
  //   int eval_width = cfg->image_shape[1];
  //   int eval_height = cfg->image_shape[0];
  //   int eval_num_class = cfg->class_num;

  //   int blob_out_len = length;
  //   int seg_out_len = eval_height * eval_width * eval_num_class;
  //   if (blob_out_len != seg_out_len) {
  //       return -1;
  //   }

  //   int res_size = eval_width * eval_height;
  //   std::vector<uchar> _mask(res_size);
  //   std::vector<uchar> _scoremap(res_size);
    
  //   // post process
  //   std::vector<int> out_shape{eval_num_class, eval_height, eval_width};
  //   PostProcessor::argmax(p_out, out_shape, _mask, _scoremap);
  //   cv::Mat mask_png = cv::Mat(eval_height, eval_width, CV_8UC1);

  //   mask_png.data = _mask.data();

  //   cv::Mat scoremap_png = cv::Mat(eval_height, eval_width, CV_8UC1);
  //   scoremap_png.data = _scoremap.data();

  //   int recover_height = eval_height / datas->scale_factor[1];
  //   int recover_width = eval_width / datas->scale_factor[0];
  //   cv::Mat recover_png = cv::Mat(recover_height, recover_width, CV_8UC1);
  //   cv::resize(scoremap_png, recover_png,
  //       img.size(), 0, 0, cv::INTER_CUBIC);

  //   cv::threshold(recover_png, recover_png, 0, 255, cv::THRESH_BINARY);

	// cv::Mat new_cv_image;
	// if (img.channels() == 1) { cv::cvtColor(*img, new_cv_image, cv::COLOR_GRAY2BGR); }
	// else if (img.channels() == 3) { img.copyTo(new_cv_image); }
	// else { return IMAGE_TYPE_NOT_SUPPORT; }

  //   cv::Mat new_big_mask = recover_png;
	// cv::Mat rgb_background = cv::Mat::zeros(img.size(), CV_8UC3);
	// rgb_background = cv::Scalar(255, 128, 128);
	// cv::Mat real_box = new_cv_image.clone();
	// cv::Mat new_mask = real_box * 0.5 + rgb_background * 0.5;

	// // spdlog::get("logger")->info(new_cv_image.channels() << "  " << new_mask.channels() << "   " << new_big_mask.channels());

	// new_mask.copyTo(new_cv_image, new_big_mask);

  //   DetInfoPD det_info;
  //   det_info.mask = new_cv_image.clone();
  //   det_infos.push_back(det_info);

    
  //   if (log_info_->log_level_3){
  //       std::string mask_save_name = log_info_->debug_image_path + "/" + \
  //                       std::to_string(log_info_->counter()) + "_mask.png";
  //       cv::imwrite(mask_save_name, mask_png);
  //               spdlog::get("logger")->info("cv::imwrite...");


  //       std::string scoremap_save_name = log_info_->debug_image_path + "/" + \
  //                       std::to_string(log_info_->counter()) + "_scoremap.png";
  //       // std::string scoremap_save_name = nname + std::string("_scoremap.png");
  //       cv::imwrite(scoremap_save_name, scoremap_png);
  //       // spdlog::get("logger")->info("save mask of [" << fname << "] done");


  //       // std::string recover_name = nname + std::string("_recover.png");
  //       std::string recover_name = log_info_->debug_image_path + "/" + \
  //                   std::to_string(log_info_->counter()) + "_recover.png";
  //       cv::imwrite(recover_name, recover_png); 

  //       std::string new_cv_image_name = log_info_->debug_image_path + "/" + \
  //                   std::to_string(log_info_->counter()) + "_new_cv_image.png";
  //       cv::imwrite(new_cv_image_name, new_cv_image); 

  //   }

    return 0;
}

// int SegPredictor::analysis_predict(const std::vector<std::string>& imgs) {
//     int config_batch_size = _model_config._batch_size;
//     int channels = _model_config._channels;
//     int eval_width = _model_config._resize[0];
//     int eval_height = _model_config._resize[1];
//     auto total_size = imgs.size();
//     int default_batch_size = std::min(config_batch_size,
//                                         static_cast<int>(total_size));
//     int batch = total_size / default_batch_size
//                 + ((total_size % default_batch_size) != 0);
//     int batch_buffer_size = default_batch_size * channels
//                             * eval_width * eval_height;
//     auto& input_buffer = _buffer;
//     auto& org_width = _org_width;
//     auto& org_height = _org_height;
//     auto& imgs_batch = _imgs_batch;
//     input_buffer.resize(batch_buffer_size);
//     org_width.resize(default_batch_size);
//     org_height.resize(default_batch_size);
//     for (int u = 0; u < batch; ++u) {
//         int batch_size = default_batch_size;
//         if (u == (batch - 1) && (total_size % default_batch_size)) {
//             batch_size = total_size % default_batch_size;
//         }
//         int real_buffer_size = batch_size * channels
//                                 * eval_width * eval_height;
//         std::vector<paddle::PaddleTensor> feeds;
//         input_buffer.resize(real_buffer_size);
//         org_height.resize(batch_size);
//         org_width.resize(batch_size);
//         for (int i = 0; i < batch_size; ++i) {
//             org_width[i] = org_height[i] = 0;
//         }
//         imgs_batch.clear();
//         for (int i = 0; i < batch_size; ++i) {
//             int idx = u * default_batch_size + i;
//             imgs_batch.push_back(imgs[idx]);
//         }
//         if (!_preprocessor->batch_process(imgs_batch,
//                                             input_buffer.data(),
//                                             org_width.data(),
//                                             org_height.data())) {
//             return -1;
//         }
//         auto im_tensor = _main_predictor->GetInputTensor("image");
//         if (!_model_config._use_pr) {
//             im_tensor->Reshape({ batch_size, channels,
//                                 eval_height, eval_width });
//         } else {
//             im_tensor->Reshape({ batch_size, eval_height,
//                             eval_width, channels});
//         }
//         im_tensor->copy_from_cpu(input_buffer.data());
//         auto t1 = std::chrono::high_resolution_clock::now();
//         _main_predictor->ZeroCopyRun();
//         auto t2 = std::chrono::high_resolution_clock::now();
//         auto duration = duration_cast<std::chrono::microseconds>
//                         (t2 - t1).count();
//         spdlog::get("logger")->info("runtime = " << duration);
//         auto output_names = _main_predictor->GetOutputNames();
//         auto output_t = _main_predictor->GetOutputTensor(
//                                             output_names[0]);
//         std::vector<int> output_shape = output_t->shape();
//         int out_num = 1;
//         spdlog::get("logger")->info("size of outputs[" << 0 << "]: (");
//         for (int j = 0; j < output_shape.size(); ++j) {
//             out_num *= output_shape[j];
//             spdlog::get("logger")->info(output_shape[j] << ",");
//         }
//         spdlog::get("logger")->info(")");
//         if (_model_config._use_pr) {
//                 std::vector<int64_t> out_data;
//                 out_data.resize(out_num);
//                 output_t->copy_to_cpu(out_data.data());
//                 std::vector<uchar> mask_data;
//                 mask_data.resize(out_num);
//                 auto addr = reinterpret_cast<int64_t*>(out_data.data());
//                 for (int r = 0; r < out_num; ++r) {
//                     mask_data[r] = (int)(addr[r]);
//                 }
//                 for (int r = 0; r < batch_size; ++r) {
//                     cv::Mat mask_png = cv::Mat(eval_height, eval_width, CV_8UC1);
//                     mask_png.data = mask_data.data() + eval_height*eval_width*r;
//                     auto name = imgs_batch[r];
//                     auto pos = name.rfind(".");
//                     name[pos] = '_';
//                     std::string mask_save_name = name + "_mask.png";
//                     cv::imwrite(mask_save_name, mask_png);
//                 }
//                 continue;
//         }
//         std::vector<float> out_data;
//         out_data.resize(out_num);
//         output_t->copy_to_cpu(out_data.data());
//         for (int i = 0; i < batch_size; ++i) {
//             float* out_addr = out_data.data()
//                             + (out_num / batch_size) * i;
//             output_mask(imgs_batch[i], out_addr, out_num / batch_size,
//                         &org_height[i], &org_width[i]);
//         }
//     }
//     return 0;
// }


// int SegPredictor::display_instances(cv::Mat &cv_image, std::vector<DetInfoPD> &det_infos)
// {
//     std::vector<cv::Scalar> m_colors;
// 	m_colors.push_back(cv::Scalar(255, 128, 128));
// 	m_colors.push_back(cv::Scalar(255, 128, 0));
// 	m_colors.push_back(cv::Scalar(128, 255, 0));
// 	m_colors.push_back(cv::Scalar(255, 138, 197));
// 	m_colors.push_back(cv::Scalar(0, 0, 255));
// 	m_colors.push_back(cv::Scalar(128, 128, 255));
// 	m_colors.push_back(cv::Scalar(128, 0, 128));
// 	m_colors.push_back(cv::Scalar(255, 128, 255));
// 	m_colors.push_back(cv::Scalar(128, 128, 0));
// 	m_colors.push_back(cv::Scalar(64, 128, 128));
// 	m_colors.push_back(cv::Scalar(0, 128, 0));
// 	m_colors.push_back(cv::Scalar(128, 128, 128));

// 	cv::Mat new_cv_image;
// 	if (cv_image.channels() == 1) { cv::cvtColor(cv_image, new_cv_image, cv::COLOR_GRAY2BGR); }
// 	else if (cv_image.channels() == 3) { cv_image.copyTo(new_cv_image); }
// 	else { return IMAGE_TYPE_NOT_SUPPORT; }

//     cv::Mat new_big_mask = det_infos[0].mask;
// 	cv::Mat rgb_background = cv::Mat::zeros(cv_image.size(), CV_8UC3);
// 	rgb_background = cv::Scalar(m_colors[det_info.class_idx]);
// 	cv::Mat real_box;
// 	new_cv_image(detect_info.detect_box).copyTo(real_box);
// 	cv::Mat new_mask = real_box * 0.4 + rgb_background * 0.6;

// 	// spdlog::get("logger")->info(new_cv_image.channels() << "  " << new_mask.channels() << "   " << new_big_mask.channels());

// 	new_mask.copyTo(new_cv_image(detect_info.detect_box), new_big_mask);
// 	/*cv::imwrite("debug_color_text.jpg", new_cv_image);*/
// 	return 0;
// }

}  // namespace PaddleSolution
